﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;

namespace LowLevelGraphics.Filter
{
    public enum PREDEFINED_COLORLIST
    {
        AUTUMN,
        BONE,
        COLORCUBE,
        COOL,
        COPPER,
        FLAG,
        GRAY,
        HOT,
        HSV,
        JET,
        LINES,
        PINK,
        PRISM,
        SPRING,
        SUMMER,
        WHITE,
        WINTER
    }

    /// <summary>
    /// This converts a given image into its color dependant pseudo color.
    /// i.e. each gray level color is another RGB color assigned.
    /// 
    /// This only works with gray images. 
    /// 
    /// Maybe you got a clinical / medical image in gray values.
    /// Often then pseudocolors are used to estimate differences.
    /// </summary>
    /// 
    public class Gray2PSeudoColor : BaseImageFilter
    {
        protected Dictionary<Color, Color> m_aColor = Definitions.PseudoColorList;
        protected Dictionary<PREDEFINED_COLORLIST, string> aDict = new Dictionary<PREDEFINED_COLORLIST, string>();
        protected PREDEFINED_COLORLIST m_PREDEFINED_COLORLIST = PREDEFINED_COLORLIST.HOT;

        /// <summary>
        /// default constructor
        /// </summary>
        public Gray2PSeudoColor()
            //: this(Definitions.PseudoColorList)
        {
            PredefinedColorList();
        }

        /// <summary>
        /// use this constructor to give a predefined color list
        /// </summary>
        public Gray2PSeudoColor(PREDEFINED_COLORLIST _preDefinedColorList)
            : this()
        {
            PREDEFINED_COLORLIST = _preDefinedColorList;
        }

        /// <summary>
        /// Specify a color lut
        /// </summary>
        /// <param name="_aColor"></param>
        public Gray2PSeudoColor(Dictionary<Color,Color> _aColor)
        {
            m_aColor = _aColor;
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_gray2PSeudoColor"></param>
        internal Gray2PSeudoColor(Gray2PSeudoColor _gray2PSeudoColor)
        {
            this.m_aColor = _gray2PSeudoColor.m_aColor;
        }

        /// <summary>
        /// gets or sets PREDEFINED_COLORLIST
        /// </summary>
        public PREDEFINED_COLORLIST PREDEFINED_COLORLIST
        {
            set
            {
                m_aColor = ((ColorList)typeof(ColorList).GetProperty(aDict[value]).GetValue(typeof(ColorList), null)).PseudoColorList;
                m_PREDEFINED_COLORLIST = value;
            }
            get { return m_PREDEFINED_COLORLIST; }
        }

        /// <summary>
        /// gets or sets pseudo color list
        /// </summary>
        public Dictionary<Color, Color> PseudoColorList
        {
            get { return m_aColor; }
            set { m_aColor = value; }
        }

        /// <summary>
        /// Predefined color list
        /// </summary>
        protected void PredefinedColorList()
        {
            aDict.Clear();
            foreach(PREDEFINED_COLORLIST predefinedColorList in Enum.GetValues(typeof(PREDEFINED_COLORLIST)))
            {
                aDict.Add(predefinedColorList, predefinedColorList.ToString());
            }
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            if (m_aColor.Count == 0 || m_aColor == null) return _bitmap;
            UnsafeBitmap bitmap = _bitmap;

            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            Color color = Color.Transparent;

            int y = 0;
            int x = 0;
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    color = bitmap.GetPixel(x,y);
                    if (m_aColor.ContainsKey(color))
                    {
                        bitmap.SetPixel(x, y, m_aColor[color]);
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// used to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Gray2PSeudoColor(this);
        }
    }
}
